//--------------------------------------------------------------------------------------------
//   : 
//      Component name  : fpmul_stage1
//      Author          : 
//      Company         : 
//
//      Description     : 
//
//
//--------------------------------------------------------------------------------------------


module FPmul_stage1(FP_A, FP_B, clk, A_EXP, A_SIG, B_EXP, B_SIG, SIGN_out_stage1, isINF_stage1, isNaN_stage1, isZ_tab_stage1);
   input [31:0]  FP_A;
   input [31:0]  FP_B;
   input         clk;
   output [7:0]  A_EXP;
   reg [7:0]     A_EXP;
   output [31:0] A_SIG;
   reg [31:0]    A_SIG;
   output [7:0]  B_EXP;
   reg [7:0]     B_EXP;
   output [31:0] B_SIG;
   reg [31:0]    B_SIG;
   output        SIGN_out_stage1;
   reg           SIGN_out_stage1;
   output        isINF_stage1;
   reg           isINF_stage1;
   output        isNaN_stage1;
   reg           isNaN_stage1;
   output        isZ_tab_stage1;
   reg           isZ_tab_stage1;
   
   
   wire [7:0]    A_EXP_int;
   wire          A_SIGN;
   wire [31:0]   A_SIG_int;
   wire          A_isINF;
   wire          A_isNaN;
   wire          A_isZ;
   wire [7:0]    B_EXP_int;
   wire          B_SIGN;
   wire [31:0]   B_SIG_int;
   wire          B_isINF;
   wire          B_isNaN;
   wire          B_isZ;
   wire          SIGN_out_int;
   reg           isINF_int;
   reg           isNaN_int;
   reg           isZ_tab_int;
   
   
   always @(posedge clk)
      
      begin
         SIGN_out_stage1 <= SIGN_out_int;
         A_EXP <= A_EXP_int;
         A_SIG <= A_SIG_int;
         isINF_stage1 <= isINF_int;
         isNaN_stage1 <= isNaN_int;
         isZ_tab_stage1 <= isZ_tab_int;
         B_EXP <= B_EXP_int;
         B_SIG <= B_SIG_int;
      end
   
   
   always @(A_isINF or A_isNaN or A_isZ or B_isINF or B_isNaN or B_isZ)
   begin: exceptions_truth_process
      if ((A_isINF == 1'b0) & (A_isNaN == 1'b0) & (A_isZ == 1'b0) & (B_isINF == 1'b0) & (B_isNaN == 1'b0) & (B_isZ == 1'b0))
      begin
         isZ_tab_int <= 1'b0;
         isINF_int <= 1'b0;
         isNaN_int <= 1'b0;
      end
      else if ((A_isINF == 1'b1) & (B_isZ == 1'b1))
      begin
         isZ_tab_int <= 1'b0;
         isINF_int <= 1'b0;
         isNaN_int <= 1'b1;
      end
      else if ((A_isZ == 1'b1) & (B_isINF == 1'b1))
      begin
         isZ_tab_int <= 1'b0;
         isINF_int <= 1'b0;
         isNaN_int <= 1'b1;
      end
      else if (A_isINF == 1'b1)
      begin
         isZ_tab_int <= 1'b0;
         isINF_int <= 1'b1;
         isNaN_int <= 1'b0;
      end
      else if (B_isINF == 1'b1)
      begin
         isZ_tab_int <= 1'b0;
         isINF_int <= 1'b1;
         isNaN_int <= 1'b0;
      end
      else if (A_isNaN == 1'b1)
      begin
         isZ_tab_int <= 1'b0;
         isINF_int <= 1'b0;
         isNaN_int <= 1'b1;
      end
      else if (B_isNaN == 1'b1)
      begin
         isZ_tab_int <= 1'b0;
         isINF_int <= 1'b0;
         isNaN_int <= 1'b1;
      end
      else if (A_isZ == 1'b1)
      begin
         isZ_tab_int <= 1'b1;
         isINF_int <= 1'b0;
         isNaN_int <= 1'b0;
      end
      else if (B_isZ == 1'b1)
      begin
         isZ_tab_int <= 1'b1;
         isINF_int <= 1'b0;
         isNaN_int <= 1'b0;
      end
      else
      begin
         isZ_tab_int <= 1'b0;
         isINF_int <= 1'b0;
         isNaN_int <= 1'b0;
      end
   end
   
   assign SIGN_out_int = A_SIGN ^ B_SIGN;
   
   
   UnpackFP I0(.FP(FP_A), .SIG(A_SIG_int), .EXP(A_EXP_int), .SIGN(A_SIGN), .isNaN(A_isNaN), .isINF(A_isINF), .isZ(A_isZ), .isDN());
   
   UnpackFP I1(.FP(FP_B), .SIG(B_SIG_int), .EXP(B_EXP_int), .SIGN(B_SIGN), .isNaN(B_isNaN), .isINF(B_isINF), .isZ(B_isZ), .isDN());
   
endmodule
